package xxl.signals.impl 
{
	import flash.errors.IllegalOperationError;
	import xxl.signals.api.ISignal;
	import xxl.signals.api.ISlot;
	import xxl.signals.util.SignalUtil;
	
	/**
	 * 同一时间只能注册一个方法
	 * @author XXL
	 */
	public class MonoSignal implements ISignal 
	{
		protected var _valueClasses:Array;
		protected var slot:ISlot;
		
		public function MonoSignal(...valueClasses) 
		{
			this.valueClasses = (valueClasses.length == 1 && valueClasses[0] is Array) ? valueClasses[0] : valueClasses;
		}
		
		protected function registerListener(listener:Function, once:Boolean = false):ISlot
		{
			if (slot)
			{
				throw new IllegalOperationError("mono一次只能添加一个listener");
			}
			return (slot = new Slot(listener, this, once));
		}
		
		/* INTERFACE xxl.signals.core.ISignal */
		
		public function add(listener:Function):ISlot 
		{
			return registerListener(listener);
		}
		
		public function addOnce(listener:Function):ISlot 
		{
			return registerListener(listener, true);
		}
		
		public function dispatch(...valueObjects):void 
		{
			SignalUtil.VerifyDispatch(valueClasses, valueObjects);
			
			if (slot)
			{
				slot.execute(valueObjects);
			}
		}
		
		public function remove(listener:Function):ISlot 
		{
			if (slot && slot.listener == listener)
			{
				const theSlot:ISlot = slot;
				slot = null;
				return theSlot;
			}
			return null;
		}
		
		public function removeAll():void 
		{
			if (slot)
			{
				slot.remove();
			}
		}
		
		public function get valueClasses():Array 
		{
			return _valueClasses;
		}
		
		public function set valueClasses(value:Array):void 
		{
			SignalUtil.VerifyValueClasses(value);
			_valueClasses = value ? value.concat() : [];
		}
		
		public function get numListeners():int 
		{
			return slot ? 1 : 0;
		}
		
	}

}